﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;

namespace ExcelExportLib
{
    [XmlRoot("Row")]
    public class ExcelRow : IXmlSerializable
    {
        /// <summary> Row number in table </summary>
        public int index=1;
        /// <summary> Number of last cell in row minus 1 </summary>
        private int lastCellIndex = 0;

        /// <summary> Array of cells in row </summary>
        public List<ExcelCell> cells=new List<ExcelCell>();

        /// <summary>Table wich contains this row</summary>
        internal ExcelTable parentTable = null;

        /// <summary> Constructor </summary>
        public ExcelRow()
        {
            this.index = 1;
        }

        /// <summary> Adds new cell </summary>
        public ExcelCell AddCell(ExcelCell ec)
        {
            //throw and error if this cell already added in some row. 
            //I think there must be something like Clone() function wich recreates this ExcelCell object
            //and then added it to row
            if(ec.parent_row!=null)
                throw new ArgumentException("Same cell object already added in some row. Create new cell object!");

            lastCellIndex++;
            ec.index = lastCellIndex;
            ec.parent_row = this;
            cells.Add(ec);
            return ec;
        }

        /// <summary>Adds new cell with date/time </summary>
        /// <param name="edt">Type of DateTime value</param>
        /// <param name="date">Added date/time</param>
        /// <returns>newly created cell</returns>
        public ExcelCell AddCell(eDateType edt, DateTime date)
        {
            ExcelCell cell = new ExcelCell(edt, date);
            AddCell(cell);
            cell.parent_row = this;
            return cell;
        }

        /// <summary> Adds new number cell </summary>
        /// <returns>newly created cell</returns>
        public ExcelCell AddCell(long num)
        {
            ExcelCell cell = new ExcelCell(num);
            AddCell(cell);
            cell.parent_row = this;
            return cell;
        }

        /// <summary> Adds new number cell </summary>
        /// <returns>newly created cell</returns>
        public ExcelCell AddCell(double num)
        {
            ExcelCell cell = new ExcelCell(num);
            AddCell(cell);
            cell.parent_row = this;
            return cell;
        }

        /// <summary> Adds new number cell </summary>
        /// <returns>newly created cell</returns>
        public ExcelCell AddCell(decimal num)
        {
            ExcelCell cell = new ExcelCell(num);
            AddCell(cell);
            cell.parent_row = this;
            return cell;
        }

        /// <summary> Adds new string cell</summary>
        /// <returns>newly created cell</returns>
        public ExcelCell AddCell(string s)
        {
            ExcelCell cell = new ExcelCell(s);
            AddCell(cell);
            cell.parent_row = this;
            return cell;
        }

        /// <summary>Adds new number cell with percent symbol</summary>
        /// <returns>newly created cell</returns>
        public ExcelCell AddCell(double v, bool percent)
        {
            ExcelCell cell = new ExcelCell(v, percent);
            AddCell(cell);
            cell.parent_row = this;
            return cell;
        }

        /// <summary>Adds new cell in position cindex</summary>
        /// <param name="cindex">new cell position</param>
        /// <param name="ec">cell for add</param>
        public ExcelCell AddCell(int cindex, ExcelCell ec)
        {
            if (CheckCellIndex(index))
                throw new SystemException("Cell with index " + index + " already exists!");

            if(lastCellIndex<cindex)
                lastCellIndex=cindex;

            ec.index = cindex;
            cells.Add(ec);
            ec.parent_row = this;
            return ec;
        }

        /// <summary> Adds new hyperlink cell with uri = string</summary>
        /// <returns>newly created cell</returns>
        public ExcelCell AddCell(string caption, string hRef)
        {
                        ExcelCell cell = new ExcelCell(caption,hRef);
            AddCell(cell);
            cell.parent_row = this;
            return cell;
        }
        /// <summary> Adds new hyperlink cell with uri = other cell</summary>
        /// <returns>newly created cell</returns>
        public ExcelCell AddCell(string caption, ExcelTable hRefTable, ExcelCell hRefCell)
        {
            //string _hRef = string.Format("#'{0}'!{1}",hRefTable.tableName , hRefCell.GetPosition().ToString());
            string _hRef = string.Format("#{0}", hRefCell.GetPosition().ToString());
            ExcelCell cell = new ExcelCell(caption, _hRef);
            AddCell(cell);
            cell.parent_row = this;
            return cell;
        }
        /// <summary>Check if cell with this index already exists </summary>
        /// <returns>true if cell already exists</returns>
        public bool CheckCellIndex(int index)
        {
            foreach (ExcelCell cell in cells)
                if (cell.index == index)
                    return true;
            return false;
        }

        /// <summary>Adds next added cell index by 1</summary>
        public void SkipCell()
        {
            lastCellIndex++;
        }

        /// <summary>Adds next added cell index by n</summary>
        public void SkipCell(int n)
        {
            lastCellIndex += n;
        }


        #region IXmlSerializable Members

        public System.Xml.Schema.XmlSchema GetSchema()
        {
            return null;
        }

        public void ReadXml(System.Xml.XmlReader reader)
        {
            throw new NotImplementedException();
        }

        public void WriteXml(System.Xml.XmlWriter writer)
        {
            writer.WriteExcelAttribute("Index", index); 

            foreach(ExcelCell ec in cells)
            {
                writer.WriteStartElement("Cell");
                ec.WriteXml(writer);
                writer.WriteEndElement();
            }
        }

        #endregion
    }
}
